home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir42 / c7105.zip / CHILD.TPX < prev    next >
Text File  |  1994-03-02  |  24KB  |  466 lines

  1. #!┌───────────────────────────┤Template Segment├───────────┬─────────────────┐
  2. #!│                               CHILD.TPX                │Version: 3007.105│
  3. #!├───────────────────────────────┤Contents├───────────────┴─────────────────┤
  4. #!│Structure             Type       Description                              │
  5. #!│────────────────────  ─────────  ─────────────────────────────────────────│
  6. #!│Child                 PROCEDURE  Update a batch of child records          │
  7. #!├───────────────────────────────┤Comments├─────────────────────────────────┤
  8. #!│Version   Comments                                                        │
  9. #!│────────  ────────────────────────────────────────────────────────────────│
  10. #!│3007.000  Release of CDD3 version 3007 templates                          │
  11. #!│3007.102  Repaired CHILD Procedure                                        │
  12. #!│3007.105  Repaired CHILD Procedure                                        │
  13. #!└──────────────────────────────────────────────────────────────────────────┘
  14. #!
  15. #PROCEDURE(Child,'Update child records from a parent'),SCREEN,PULLDOWN
  16. #!
  17. #!┌──────────────────────────┤Procedure Template├──────────┬─────────────────┐
  18. #!│                                 Child                  │Version: 3007.105│
  19. #!├──────────────────────────────┤Description├─────────────┴─────────────────┤
  20. #!│ The Child template scrolls child records from a file on the screen       │
  21. #!│ and allows updating the records on the same screen.  A parent            │
  22. #!│ file must be identified and a valid parent record must be in memory      │
  23. #!│ when this procedure is called.                                           │
  24. #!│                                                                          │
  25. #!│ The QUEUE will contain all children records for a particular             │
  26. #!│ Parent record.  Changes to the children records are made to the          │
  27. #!│ QUEUE and are only written to disk upon completion of the OK             │
  28. #!│ button.  The update process is framed within a logged transaction.       │
  29. #!│ The child file must use a file driver which supports transaction         │
  30. #!│ processing in order to use this template.                                │
  31. #!│                                                                          │
  32. #!│ The Child template's screen will contain a scrolling listbox             │
  33. #!│ With Add, Change, Delete, Ok and Cancel pushbuttons and a fixed          │
  34. #!│ field entry area with Save and Exit Buttons.                             │
  35. #!│                                                                          │
  36. #!│ The Child template does not support autonumbering of keys.               │
  37. #!├───────────────────────────────┤Comments├─────────────────────────────────┤
  38. #!│Version   Comments                                                        │
  39. #!│────────  ────────────────────────────────────────────────────────────────│
  40. #!│3007.000  Release of CDD3 version 3007 templates                          │
  41. #!│3007.102  Repaired the FillQueues ROUTINE to work correctly with Multi-   │
  42. #!│          Part Keys.                                                      │
  43. #!│3007.105  Completed support for PullDowns                                 │
  44. #!│          Moved the #SET of %FirstNonFixedRow from it's previous place    │
  45. #!│          inside an #IF structure, to right after the #SET of %FixRows    │
  46. #!│          Added #INSERT of StandardHeader                                 │
  47. #!└──────────────────────────────────────────────────────────────────────────┘
  48. #!
  49. #DISPLAY('')
  50. #INSERT(%StandardHeader)
  51. #PROTOTYPE('')
  52. #PROMPT('First Upd&ate Field',FIELD),%FirstUpdateField
  53. #PROMPT('Parent F&ile',FILE),%ParentFile
  54. #PROMPT('Exit on &Null Parent',CHECK),%NullParentExit
  55. #PROMPT('Upd&ate Parent on OK',CHECK),%PutParent
  56. #INSERT(%SetChildSymbols)
  57.  
  58. %Procedure       PROCEDURE
  59.  
  60. #INSERT(%FileControl)
  61. #FIX(%File,%Primary)
  62. RecordQueue      QUEUE,PRE(SAV)
  63. Line              STRING(%ScreenFieldQueueSize) #<! Line to be scrolled
  64. SaveRecord        LIKE(%FilePre:Record),PRE(SAV)
  65. SkipRecord        BYTE
  66. #FIX(%Key,%PrimaryKey)
  67. #SET(%FirstField, %Null)
  68. #SET(%SortString,%Null)
  69. #FOR(%KeyField)
  70.   #FIX(%Field,%KeyField)
  71.   #IF(%FirstField = %Null)
  72.     #SET(%FirstField, %KeyField)
  73.     #SET(%FirstFieldSequence, %KeyFieldSequence)
  74.   #ENDIF
  75.   #IF(%KeyFieldSequence <> 'DESCENDING')
  76.     #SET(%SortString, (CLIP(LEFT(%SortString)) & ',+SAV:' & %FieldID))
  77.   #ELSE
  78.     #SET(%SortString, (CLIP(LEFT(%SortString)) & ',-SAV:' & %FieldID))
  79.   #ENDIF
  80. #ENDFOR
  81. RecordPosition    STRING(256)
  82. #FOR(%Field)
  83.   #IF(%FieldType = 'MEMO')
  84.     #SET(%MemoField,%FieldID)
  85. %FieldID          STRING(SIZE(%Field))         #<! Restore the Memos
  86.   #ENDIF
  87. #ENDFOR
  88.                  .                             #<!End Queue structure
  89.  
  90. FirstPage        BYTE(1)                         ! Page display variable
  91. EntryMode        BYTE(0)                         ! Toggles for entry mode
  92. ScrollMode       EQUATE(1)                       !   ScrollMode or
  93. UpdateMode       EQUATE(2)                       !   UpdateMode
  94. DRecs            SHORT                           ! Number of Child records
  95. QRecs            SHORT                           ! Number of QUEUE records
  96. I                BYTE                            ! QUEUE record pointer
  97. ChildAction      BYTE(0)                         ! Update mode
  98. NoMoreFields     BYTE(0)                         ! No more fields
  99. TransactionError BYTE(0)                         ! Transaction Error
  100. RecordEntryOne   BYTE(0)                         ! Starting record in QUEUE
  101. %LocalData
  102. %ScreenStructure
  103. #IF(%PullDown)
  104. %PulldownStructure
  105. SAV::PullDownOpened BYTE(0)
  106. #ENDIF
  107. #EMBED('Data Section')
  108.  
  109.   CODE
  110.   #EMBED('Setup Procedure')
  111.   #INSERT(%NullParentCheck)                     #!Return if blank parent
  112.   #INSERT(%FileControl)
  113.   #INSERT(%HoldParentRecord)                    #!Hold the parent record
  114.   OPEN(SCREEN)                                   !Open the screen
  115.   #EMBED('Setup Screen')
  116.   #IF(%Pulldown)                                #!If a Pulldown exists
  117.   OPEN(%Pulldown)                              #<!Open the Pulldown
  118.   SAV::PullDownOpened = True
  119.   #EMBED('Setup Pulldown')                       #! Embedded Source Code
  120.   #ENDIF
  121.   DO EnterScrollMode                             !Select Scrolling mode
  122.   DO FillQueues                                  !Fill the Queues
  123.   DRecs = RECORDS(RecordQueue)                   !Save the number of children
  124.   #FIX(%File,%Primary)
  125.   DISPLAY                                        !Show the listbox
  126.   LOOP
  127.     #INSERT(%GenerateFormulas)                  #!Generate all formulas
  128.     #EMBED('Top of Accept Loop')
  129.     CASE SELECTED()                              !Jump to setup routine
  130.       OF NoMoreFields
  131.         SELECT(?Save)
  132.         DO EnterScrollMode                       ! Switch modes
  133.       #INSERT(%ScreenSetupRoutines)
  134.     END                                          !End CASE
  135.     ACCEPT                                       !Accept user input
  136.  
  137.     CASE KEYCODE()
  138.     #FOR(%HotKey)
  139.     OF %HotKey                                 #<!User defined HotKey
  140.       %HotKeyProc                              #<!HotKey Procedure
  141.     #ENDFOR
  142.     END
  143.  
  144.     IF EntryMode = ScrollMode                    !If processing the ScrollMode
  145.       IF RECORDS(RecordQueue) = %FixRows       #<!  If deleted last record.
  146.         DISABLE(?Change)                         !    Disable the change button
  147.         DISABLE(?Delete)                         !    Disable the delete button
  148.       END                                        !  End IF
  149.       CASE FIELD()                               ! Jump to edit routine
  150.       OF ?List                                   ! Process the List box
  151.         GET(RecordQueue,CHOICE())              #<! Get the Record Data
  152.         IF ERRORCODE() THEN CYCLE.               ! Cycle if no records
  153.     #FIX(%File,%Primary)
  154.         %FilePre:Record = SAV:SaveRecord       #<! Fill the fields
  155.     #FOR(%Field)
  156.       #IF(%FieldType = 'MEMO')
  157.         #SET(%MemoField,%FieldID)
  158.         %Field = SAV:%FieldID                  #<!  Restore the Memos
  159.       #ENDIF
  160.     #ENDFOR
  161.         #INSERT(%GetChildSecondary)
  162.         DISPLAY                                  ! and re-display
  163.         IF KEYCODE() = MouseLeft2                ! On Mouse double click
  164.           PRESS(EnterKey)                        !  Press the EnterKey
  165.         END                                      ! End IF
  166.       OF ?Insert                                 ! Process the Insert Button
  167.         #FIX(%File,%Primary)
  168.         ChildAction = AddRecord                  !  Set to adding a record
  169.         #INSERT(%ClearFileFields)              #<!  Clear the record for entry
  170.         #INSERT(%GetChildSecondary)
  171.         DO EnterUpdateMode                       ! Switch to update mode
  172.         #IF(%InitRoutine)                        #<!Field(s) initial value
  173.         DO InitializeFields                      !Initial values from dictionary
  174.         #ENDIF
  175.       OF ?Change                                 ! Process the Change Button
  176.         ChildAction = ChangeRecord               !  Set to Changing a record
  177.         DO EnterUpdateMode                       !  Switch modes
  178.       OF ?Delete                                 ! Process the Delete Button
  179.         ChildAction = DeleteRecord               !  Set to Deleting a record
  180.         DELETE(RecordQueue)                      !  Delete Record Queue Entry
  181.         #INSERT(%ClearFileFields)                #<! Clear the record for entry
  182.         DISPLAY                                  !  Redisplay the list box
  183.         IF RECORDS(RecordQueue) = %FixRows       #<! If deleted last record.
  184.           DISABLE(?Change)                       !    Disable the change button
  185.           DISABLE(?Delete)                       !    Disable the delete button
  186.           SELECT(?Insert)                        !    Select the insert button
  187.         ELSE                                     !  Else
  188.           SELECT(?List)                          !    Select the list box
  189.         END                                      !  End IF
  190.         ChildAction = 0                          !  Reset the Action
  191.         CYCLE                                    !  Cycle to accept input
  192.       OF ?Ok                                     ! Process the Ok Button
  193.         QRecs = RECORDS(RecordQueue)             !  Save the queue record count
  194.   #FIX(%File, %Primary)
  195.         #INSERT(%ClearFileFields)              #<!Clear the record buffer
  196.         TransactionError = 0                     !Clear Transaction error
  197.   #FIX(%File, %ParentFile)
  198.   #FIX(%Relation,%Primary)
  199.   #IF(%RelationType = '1:MANY')
  200.     #FOR(%RelationKeyField)
  201.       #IF(%RelationKeyFieldLink)
  202.         %RelationKeyField = %RelationKeyFieldLink #<!Assign linking field value
  203.       #ENDIF
  204.     #ENDFOR
  205.   #ENDIF
  206.         SET(%RelationKey,%RelationKey)         #<!Set to the matching record
  207.         LOGOUT(2,%Primary)                     #<!Enable transaction logging
  208.         IF ERRORCODE() = BadTranErr              !If transaction error occurs
  209.           #INSERT(%BadTrxPrimaryMsg)
  210.           SELECT(?Ok)                            ! Reselect the Ok button
  211.           CYCLE                                  ! Cycle to ACCEPT input
  212.         END                                      !End IF
  213.         #INSERT(%UpdateChildRecords)
  214.         IF TransactionError                      !If transaction error occurs
  215.           #INSERT(%BadTrxChildMsg)
  216.           ROLLBACK                               ! Rollback the changes.
  217.           SELECT(?List,I)                        ! Reselect the List box
  218.           PRESS(EnterKey)                        ! Setup to change record
  219.           CYCLE                                  ! Cycle to ACCEPT input
  220.         ELSE                                     !Else
  221.           COMMIT                                 ! Commit the changes to disk
  222.         END                                      !End IF
  223.         #INSERT(%PutParentFile)
  224.         DO ProcedureReturn                       ! Break to Return to Caller
  225.       OF ?Cancel                                 !Process the Cancel Button
  226.         DO ProcedureReturn                       ! Break to Return to Caller
  227.       END                                        !End CASE
  228.     ELSE                                         ! Else if update mode
  229.       #INSERT(%GetChildSecondary)
  230.       DISPLAY                                    ! Display the new record
  231.       CASE FIELD()                                   !
  232.   #FOR(%ScreenField)
  233.     #IF(%ScreenField='?OK')
  234.     #ELSIF(%ScreenField='?Cancel')
  235.     #ELSIF(%ScreenField='?Save')
  236.       OF ?Save                                   ! Process the Save Button
  237.         #FIX(%ScreenField,'?Save')               #! Set current active to ?Save
  238.         #IF(%ScreenFieldEdit)                    #! Check for Field Edits
  239.         %ScreenFieldEdit
  240.         #ENDIF
  241.         CASE ChildAction                         ! Adding or Changing?
  242.         OF AddRecord                             ! When adding a new record.
  243.           #INSERT(%FillQueueFields)
  244.           ADD(RecordQueue %SortString)         #<! Add to the sorted queue
  245.           ChildAction = 0                        ! Reset the Action value
  246.         OF ChangeRecord                          ! When changing a record
  247.           #INSERT(%FillQueueFields)
  248.           PUT(RecordQueue %SortString)         #<! Add to the queue
  249.           ChildAction = 0                        ! Reset the Action value
  250.         END                                      ! Case
  251.         SELECT(1)                                !Start with the first field
  252.         SELECT                                   !and cycle non-stop
  253.         CYCLE                                    !restart main process loop
  254.     #ELSIF(%ScreenField='?Exit')
  255.       OF ?Exit                                   ! Process the Exit Button
  256.         #FIX(%ScreenField,'?Exit')               #! Set current active to ?Exit
  257.         #IF(%ScreenFieldEdit)                    #! Check for Field Edits
  258.         %ScreenFieldEdit
  259.         #ENDIF
  260.         DO EnterScrollMode                       ! Switch modes
  261.       END
  262.     #ELSE
  263.       #INSERT(%ScreenEditRoutines)
  264.     #ENDIF
  265.   #ENDFOR
  266.     END                                          ! End IF
  267.     CASE FIELD()
  268.   #FOR(%PulldownField)
  269.     #IF(%PulldownFieldProc <> %NULL)
  270.     OF %PulldownField                          #<!For a selected menu item
  271.   %PulldownFieldProc                           #<!Call the procedure
  272.     #ENDIF
  273.   #ENDFOR
  274.     END                                          !End CASE for Pulldowns
  275.   END                                            !End LOOP
  276. !─────────────────────────────────────────────────────────────────────────────
  277. ProcedureReturn ROUTINE
  278.   #EMBED('Prior to Return')
  279.   #IF(%Pulldown)                                #!If a Pulldown exists
  280.   IF SAV::PullDownOpened
  281.     CLOSE(%Pulldown)                           #<!Open the Pulldown
  282.   END
  283.   #ENDIF
  284.   #IF(%SharedFiles)
  285.   RELEASE(%ParentFile)                         #<!Release held parent record
  286.   #ENDIF
  287.   FREE(RecordQueue)                              !Free the QUEUE memory
  288.   #EMBED('Before Closing Screen')
  289.   #EMBED('Before Closing Files')
  290.   #INSERT(%FileControl)
  291.   DO EndOfProcedureEmbed
  292.   RETURN
  293. !─────────────────────────────────────────────────────────────────────────────
  294. EndOfProcedureEmbed ROUTINE
  295. #EMBED('End of Procedure')
  296. #EMBED('Custom Routines')
  297.  
  298. !─────────────────────────────────────────────────────────────────────────────
  299. #INSERT(%ChildInitFields)
  300.  
  301. EnterScrollMode ROUTINE                          !Switch screen mode routine
  302.  
  303.   DISABLE(1,FIELDS())                            ! Disable listbox and buttons
  304.   ENABLE(?List)                                  ! Enable the list box
  305.   ENABLE(?Insert, ?Cancel)                       ! Enable the Buttons
  306.   IF RECORDS(RecordQueue) = %FixRows           #<!  If no records to scroll
  307.     IF EntryMode                                 !   If not before FillQueues
  308.       DISABLE(?Change)                           !    Disable the change button
  309.       DISABLE(?Delete)                           !    Disable the delete button
  310.       SELECT(?Insert)                            !    Select the insert button
  311.     END                                          !   End IF
  312.   ELSE                                           !  Else
  313.     SELECT(?List)                                !    Select the list box
  314.   END                                            !  End IF
  315.   EntryMode = ScrollMode                         ! Switch to scroll mode
  316.   #EMBED('Enter Scroll Mode Routine')
  317.  
  318. EnterUpdateMode ROUTINE
  319.  
  320.   EntryMode = UpdateMode                         !Switch screen mode routine
  321.   DISABLE(1,FIELDS())                            ! Disable listbox and buttons
  322.   ENABLE(?%FirstUpdateField, ?Exit)              #<! Enable the entry fields
  323.   Select(?%FirstUpdateField)                     #<! Select the first entry field
  324.   #EMBED('Enter Update Mode Routine')
  325.  
  326. FillQueues ROUTINE
  327.  
  328.   FREE(RecordQueue)                            #<!Clear the Record queue
  329.   #SET(%FixRows, '0')
  330.   #SET(%ListField,'?List')
  331.   #FIX(%ScreenField,%ListField)
  332.   #FOR(%ScreenFieldFix)
  333.     #SET(%FixRows, (%FixRows + 1))
  334.   SAV:Line = %ScreenFieldFix                   #<!Add list box fixed fields
  335.   ADD(RecordQueue %SortString)                 #<! Add to the sorted queue
  336.   DISPLAY(?List)                               #<!Blank the listbox
  337.   #ENDFOR
  338.   #SET(%FirstNonFixedRecord,(%FixRows+1))
  339.   #FIX(%File, %Primary)
  340.   #INSERT(%ClearFileFields)                    #<!Clear the Child record
  341.   #FIX(%File, %ParentFile)
  342.   #FIX(%Relation,%Primary)
  343.   #IF(%RelationType = '1:MANY')
  344.     #FOR(%RelationKeyField)
  345.       #IF(%RelationKeyFieldLink)
  346.   %RelationKeyField = %RelationKeyFieldLink    #<!Assign linking field value
  347.       #ENDIF
  348.     #ENDFOR
  349.   #ENDIF
  350.   SET(%RelationKey,%RelationKey)               #<!Set to keyed order
  351.   LOOP                                           !Get all selected records
  352.     NEXT(%Primary)                             #<!Get the next record.
  353.     IF ERRORCODE() THEN BREAK.                   !Quit if an error occurs
  354.     #INSERT(%GetChildSecondary)
  355.   #FIX(%File,%Primary)
  356.   #FIX(%Key,%PrimaryKey)
  357.   #IF(%ChildRelationField)                      #!If using a Range
  358.     #SET(%FieldCounter,%Null)
  359.     #FOR(%RelationKeyField)
  360.       #IF(%RelationKeyFieldLink)
  361.         #SET(%FieldCounter,(%FieldCounter+1))
  362.       #ENDIF
  363.     #ENDFOR
  364.     #SET(%IfWritten,%Null)
  365.     #FOR(%RelationKeyField)
  366.       #IF(%RelationKeyFieldLink)
  367.         #IF(%FieldCounter = '1')
  368.           #IF(%IfWritten)
  369.     OR %RelationKeyFieldLink <> %RelationKeyField #<!If not in Range
  370.           #ELSE
  371.     IF %RelationKeyFieldLink <> %RelationKeyField #<!If not in Range
  372.           #ENDIF
  373.           #BREAK
  374.         #ELSE
  375.           #IF(%IfWritten)
  376.     OR %RelationKeyFieldLink <> %RelationKeyField |#<!If not in Range
  377.           #ELSE
  378.     IF %RelationKeyFieldLink <> %RelationKeyField |#<!If not in Range
  379.           #ENDIF
  380.         #ENDIF
  381.         #SET(%IfWritten,'TRUE')
  382.         #SET(%FieldCounter,(%FieldCounter-1))
  383.       #ENDIF
  384.     #ENDFOR
  385.       IF RECORDS(RecordQueue) <> %FixRows      #<!  If records were added
  386.         GET(RecordQueue,%FirstNonFixedRecord)  #<!   Get first non-fixed row
  387.         RESET(%RelationKey,SAV:RecordPosition) #<!  Reset to the last entry
  388.         NEXT(%Primary)                         #<!  Reread the last entry
  389.         BREAK                                  #<!  Break out of the Loop
  390.       ELSE                                       ! Else no children found
  391.         #INSERT(%ClearFileFields)              #<!  Clear the record
  392.         BREAK                                  #<!  Break out of the Loop
  393.       END                                        ! End IF
  394.     END                                          !End IF
  395.   #ENDIF
  396.   #IF(%RecordFilterFormula)
  397.     IF ~(%RecordFilterFormula)                 #<!If Filter condition not met
  398.       CYCLE                                      ! Try another record
  399.     END                                          !End IF
  400.   #ELSE
  401.     #FOR(%Formula)
  402.       #IF(UPPER(%FormulaClass) = 'FILTER')
  403.         #IF(%FormulaType <> 'COMPUTED')
  404.     IF ~(%FormulaCondition)                    #<!If Filter condition not met
  405.       CYCLE                                      ! Try another record
  406.     END                                          !End IF
  407.         #ELSE
  408.     IF ~(%FormulaComputation)                  #<!If Filter condition not met
  409.       CYCLE                                      ! Try another record
  410.     END                                          !End IF
  411.         #ENDIF
  412.       #ENDIF
  413.     #ENDFOR
  414.   #ENDIF
  415.   #FOR(%Formula)
  416.     #IF(UPPER(%FormulaClass) = 'LIST')
  417.     #INSERT(%GenerateFormula)                   #!Generate LIST formulas
  418.     #ENDIF
  419.   #ENDFOR
  420.   #FIX(%File,%Primary)
  421.   #SET(%ListField,'?LIST')
  422.   #FIX(%ScreenField,%ListField)
  423.     SAV:Line = %ScreenFieldExpression          #<! Fill the DisplayQueue line
  424.     SAV:SaveRecord = %FilePre:Record             ! Save the record data
  425.     SAV:RecordPosition = POSITION(%RelationKey)  ! Save the record position
  426.   #FOR(%Field)
  427.     #IF(%FieldType = 'MEMO')
  428.       #SET(%MemoField,%FieldID)
  429.     SAV:%FieldID = %Field                      #<!  Restore the Memos
  430.     #ENDIF
  431.   #ENDFOR
  432.     ADD(RecordQueue %SortString)               #<! Add to the sorted queue
  433.     IF ERRORCODE() THEN BREAK.                   ! Quit out if error
  434.     IF FirstPage                                 ! If page 1
  435.       IF RECORDS(RecordQueue) = ROWS(?List)      ! If we have a full screen
  436.         FirstPage = 0                            !   turn off the page flag
  437.       END                                        !  End IF
  438.       DISPLAY(?List)                             !  Display page 1
  439.     END                                          ! End IF
  440.   END                                            !End LOOP
  441.   IF RECORDS(RecordQueue) = %FixRows           #<!If the queue is empty
  442.     IF RECORDS(%Primary)                       #<! If file is not empty
  443.       IF ?List <> %FirstEntryField             #<!  And list is not first
  444.         SELECT(1)                                !   Select the first field
  445.       ELSE                                       !  Else
  446.         DISABLE(1,FIELDS())                      !   Disable all fields
  447.         ENABLE(?Insert)                          !   Enable the Insert and
  448.         ENABLE(?Cancel)                          !   the cancel buttons
  449.         SELECT(?Insert)                          !   Select the Insert Button
  450.       END                                        !  End IF
  451.     ELSE                                         ! Else the file is empty
  452.       DISABLE(1,FIELDS())                        !   Disable all fields
  453.       ENABLE(?Insert)                            !   Enable the Insert and
  454.       ENABLE(?Cancel)                            !   the cancel buttons
  455.       SELECT(?Insert)                            !   Select the Insert Button
  456.     END                                          ! End IF
  457.   ELSE                                           !Else records exist
  458.     GET(RecordQueue,%FirstNonFixedRecord)      #<! Get first non-fixed row
  459.     RESET(%RelationKey,SAV:RecordPosition)     #<! Reset to the last entry
  460.     NEXT(%Primary)                             #<! Reread the last entry
  461.     #INSERT(%GetChildSecondary)
  462.   END                                            !End IF
  463.   DISPLAY
  464. #!
  465. #CHAIN('Report.tpx')
  466.